package com.module.zxing.widget;

import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.graphics.Rect;
import android.os.Bundle;
import android.os.Handler;
import android.util.AttributeSet;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.widget.RelativeLayout;
import android.widget.Toast;

import com.google.zxing.Result;
import com.module.zxing.R;
import com.module.zxing.camera.CameraManager;
import com.module.zxing.decode.DecodeQRCodeThread;
import com.module.zxing.utils.BeepManager;
import com.module.zxing.utils.InactivityTimer;
import com.module.zxing.utils.QRCodeHandler;

import java.io.IOException;
import java.lang.reflect.Field;

/**
 * Created by Administrator on 2016/2/5.
 */
public abstract class QRCodeView extends RelativeLayout implements SurfaceHolder.Callback{

    private static final String TAG = QRCodeView.class.getSimpleName();

    private View scan, top, bottom, left, right, container;

    private CameraManager cameraManager;

    private QRCodeHandler qrCodeHandler;

    private Rect cropRect;

    private InactivityTimer inactivityTimer;

    private BeepManager beepManager;

    private SurfaceView surfaceView;

    private SurfaceHolder surfaceHolder;

    private boolean isHasSurface = false;

    public QRCodeView(Context context, AttributeSet attrs) {

        super(context, attrs);

        LayoutInflater.from(context).inflate(R.layout.view_qr_code, this);

        cameraManager = new CameraManager(context);

        surfaceView = (SurfaceView) findViewById(R.id.view_qr_surface_view);

        scan = findViewById(R.id.view_qr_scan);

        top = findViewById(R.id.view_qr_top);

        bottom = findViewById(R.id.view_qr_bottom);

        left = findViewById(R.id.view_qr_left);

        right = findViewById(R.id.view_qr_right);

        container = findViewById(R.id.view_qr_container);

        surfaceHolder = surfaceView.getHolder();

        surfaceHolder.addCallback(this);

        top.setBackgroundColor(marginColor());

        bottom.setBackgroundColor(marginColor());

        left.setBackgroundColor(marginColor());

        right.setBackgroundColor(marginColor());

        LayoutParams layoutParams = (LayoutParams) scan.getLayoutParams();

        layoutParams.width = scanWidth();

        layoutParams.height = scanHeight();

        layoutParams = (LayoutParams) top.getLayoutParams();

        layoutParams.height = marginTop();

        inactivityTimer = new InactivityTimer(context);

        beepManager = new BeepManager(context);

    }

    @Override
    public void surfaceCreated(SurfaceHolder holder) {

        if (holder == null) {

            Log.e(TAG, "*** WARNING *** surfaceCreated() gave us a null surface!");

        }

        if (!isHasSurface) {

            isHasSurface = true;

            initCamera(holder);

        }

    }

    public void onResume(){

        qrCodeHandler = null;

        if (isHasSurface) {

            initCamera(surfaceView.getHolder());

        } else {

            surfaceView.getHolder().addCallback(this);

        }

        inactivityTimer.onResume();

    }

    public void onPause(){

        if (qrCodeHandler != null) {

            qrCodeHandler.quitSynchronously();

            qrCodeHandler = null;

        }

        inactivityTimer.onPause();

        beepManager.close();

        cameraManager.closeDriver();

        if (!isHasSurface) {

            surfaceView.getHolder().removeCallback(this);

        }

    }

    public void onDestroy() {

        inactivityTimer.shutdown();

    }

    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {

    }

    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {

    }

    private void initCamera(SurfaceHolder surfaceHolder) {

        if (surfaceHolder == null) {

            throw new IllegalStateException("No SurfaceHolder provided");

        }

        if (cameraManager.isOpen()) {

            Log.w(TAG, "initCamera() while already open -- late SurfaceView callback?");

            return;

        }

        try {

            cameraManager.openDriver(surfaceHolder);

            if (qrCodeHandler == null) {

                qrCodeHandler = new QRCodeHandler(this, cameraManager, DecodeQRCodeThread.ALL_MODE);

            }

            initCrop();

        } catch (IOException ioe) {

            Log.w(TAG, ioe);

            displayFrameworkBugMessageAndExit();

        } catch (RuntimeException e) {

            Log.w(TAG, "Unexpected error initializing camera", e);

        }

    }

    private void initCrop() {

        int cameraWidth = cameraManager.getCameraResolution().y;

        int cameraHeight = cameraManager.getCameraResolution().x;

        int[] location = new int[2];

        scan.getLocationInWindow(location);

        int cropLeft = location[0];

        int cropTop = location[1] - getStatusBarHeight();

        int cropWidth = scan.getWidth();

        int cropHeight = scan.getHeight();

        int containerWidth = container.getWidth();

        int containerHeight = container.getHeight();

        int x = cropLeft * cameraWidth / containerWidth;

        int y = cropTop * cameraHeight / containerHeight;

        int width = cropWidth * cameraWidth / containerWidth;

        int height = cropHeight * cameraHeight / containerHeight;

        cropRect = new Rect(x, y, width + x, height + y);

    }

    private int getStatusBarHeight() {

        try {

            Class<?> c = Class.forName("com.android.internal.R$dimen");

            Object obj = c.newInstance();

            Field field = c.getField("status_bar_height");

            int x = Integer.parseInt(field.get(obj).toString());

            return getResources().getDimensionPixelSize(x);

        } catch (Exception e) {

            e.printStackTrace();

        }

        return 0;

    }

    private void displayFrameworkBugMessageAndExit() {

        AlertDialog.Builder builder = new AlertDialog.Builder(getContext());

        builder.setTitle(getContext().getString(R.string.app_name));

        builder.setMessage("相机打开出错，请稍后重试");

        builder.setPositiveButton("确定", new DialogInterface.OnClickListener() {

            @Override
            public void onClick(DialogInterface dialog, int which) {

            }

            private void finish() {

            }

        });

        builder.setOnCancelListener(new DialogInterface.OnCancelListener() {

            @Override
            public void onCancel(DialogInterface dialog) {



            }

        });

        builder.show();

    }

    public void handleDecode(Result rawResult, Bundle bundle) {

        inactivityTimer.onActivity();
        beepManager.playBeepSoundAndVibrate();
        Toast.makeText(getContext(), rawResult.getText(), Toast.LENGTH_LONG).show();
//        Log.e("QRCodeHandler", (String) message.obj);
//        onResult(rawResult.getText());
//		setResult(RESULT_CODE, getIntent().putExtra("result", rawResult.getText()));

//		bundle.putInt("width", mCropRect.width());
//		bundle.putInt("height", mCropRect.height());
//		bundle.putString("result", rawResult.getText());

//		startActivity(new Intent(CaptureActivity.this, ResultActivity.class)
//				.putExtras(bundle));

    }

    public Handler getHandler() {

        return qrCodeHandler;

    }

    public CameraManager getCameraManager() {

        return cameraManager;

    }

    public Rect getCropRect() {

        return cropRect;

    }

    protected abstract int marginTop();

    protected abstract int scanWidth();

    protected abstract int scanHeight();

    protected abstract int marginColor();

}
